package com.tian.netty.executor;

import com.alibaba.fastjson.JSON;
import com.tian.dto.ChargeStationGunStatusInfo;
import com.tian.entity.ChargeStationGun;
import com.tian.entity.ChargeStationInfo;
import com.tian.enums.ChargerGunStatusEnum;
import com.tian.message.MessageReqIdPrefixConstant;
import com.tian.message.StationGunCommunicateLogMessage;
import com.tian.netty.core.ClientChannelMap;
import com.tian.netty.message.MsgType;
import com.tian.netty.message.req.ChargerLoginMsg;
import com.tian.netty.message.req.ChargerLoginReq;
import com.tian.netty.message.resp.ChargerLoginResp;
import com.tian.producer.StationGunCommunicateLogProducer;
import com.tian.util.DateUtils;
import com.tian.util.StationRedisPreKey;
import io.netty.channel.socket.SocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * {@code @description:} 充电桩登录报文识别处理
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-03-10 14:37
 * {@code @version:} 1.0
 */
@Slf4j
@Component(MsgType.MSG_TYPE_PRE + MsgType._0X_01)
public class ChargerLoginExecutor extends RequestExecutorBase {
    @Resource
    private RedissonClient redissonClient;

    @Resource
    private StationGunCommunicateLogProducer stationGunCommunicateLogProducer;

    @Override
    public void run() {
        ChargerLoginReq chargerLoginReq = new ChargerLoginReq(MsgType._0X_01, msgObject);
        ChargerLoginMsg chargerLoginMsg = chargerLoginReq.parse();

        SocketChannel hisChannel = ClientChannelMap.getSockeChannel(chargerLoginMsg.getGunNo());
        //缓存连接
        if (hisChannel == null || hisChannel != channel) {
            log.info("充电桩登录成功，充电桩编号：{}", chargerLoginMsg.getGunNo());
            //认证通过，保存电桩跟socketChannel的关系
            ClientChannelMap.add(chargerLoginMsg.getGunNo(), channel);
            //充电桩上线日志
            StationGunCommunicateLogMessage stationGunCommunicateLogMessage = new StationGunCommunicateLogMessage();
            stationGunCommunicateLogMessage.setGunNo(chargerLoginMsg.getGunNo());
            stationGunCommunicateLogMessage.setLogType(com.tian.enums.LogType.ONLINE.getType());
            stationGunCommunicateLogMessage.setLogTime(LocalDateTime.now());
            stationGunCommunicateLogMessage.setReqId(MessageReqIdPrefixConstant.CHARGE_STATION_GUN_REQ_ID_PREFIX
                    + UUID.randomUUID() + DateUtils.formatDefaultDateMs());
            stationGunCommunicateLogProducer.send(stationGunCommunicateLogMessage);

            RBucket<String> chargerOnlineBucket = redissonClient.getBucket(StationRedisPreKey.STATION_GUN_STATUS_PRE_KEY + chargerLoginMsg.getGunNo());
            ChargeStationGunStatusInfo chargeStationGunStatusInfo = JSON.parseObject(chargerOnlineBucket.get(), ChargeStationGunStatusInfo.class);
            if (chargeStationGunStatusInfo == null) {
                RBucket<String> chargeStationGunBucket = redissonClient.getBucket(StationRedisPreKey.STATION_GUN_NO_PRE_KEY + chargerLoginMsg.getGunNo());
                ChargeStationGun chargeStationGun = JSON.parseObject(chargeStationGunBucket.get(), ChargeStationGun.class);
                RBucket<String> chargeStationBucket = redissonClient.getBucket(StationRedisPreKey.STATION_PRE_KEY + chargeStationGun.getStationId());
                ChargeStationInfo chargeStationInfo = JSON.parseObject(chargeStationBucket.get(), ChargeStationInfo.class);

                chargeStationGunStatusInfo = new ChargeStationGunStatusInfo();
                chargeStationGunStatusInfo.setId(chargeStationGun.getId());
                chargeStationGunStatusInfo.setName(chargeStationGun.getGunName());
                chargeStationGunStatusInfo.setGunNo(chargeStationGun.getGunNo());
                chargeStationGunStatusInfo.setStationName(chargeStationInfo.getStationName());
                chargeStationGunStatusInfo.setGunStatus(ChargerGunStatusEnum.IDLE.getChargerStatus());

                chargerOnlineBucket.set(JSON.toJSONString(chargeStationGunStatusInfo));
                return;
            }
            chargeStationGunStatusInfo.setGunStatus(ChargerGunStatusEnum.IDLE.getChargerStatus());
            chargerOnlineBucket.set(JSON.toJSONString(chargeStationGunStatusInfo));
        }
        ChargerLoginResp chargerLoginResp = new ChargerLoginResp(MsgType._0X_02);
        Map<String, Object> respBody = new HashMap<String, Object>();
        respBody.put("chargerNo", chargerLoginMsg.getGunNo());

        chargerLoginResp.setResponseBody(respBody);

        channel.writeAndFlush(chargerLoginResp.getMsgObject());
    }
}
